/*
# Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#  * Neither the name of NVIDIA CORPORATION nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef OPENGL_GLSL_SHADERS
#define OPENGL_GLSL_SHADERS

const char * line_render_shader_fs_code = 
"uniform layout (location = 1) vec4 gColor;\n"
"out vec4 FragColor;\n"
"\n"
"void main()\n"
"{\n"
"    FragColor = gColor;\n"
"}\n"
"\n"
"";

const char * image_render_shader_fs_code = 
"in vec2 TexCoord0;\n"
"out vec4 FragColor;\n"
"\n"
"uniform layout (binding = 0) sampler2D gSampler;\n"
"uniform layout (location = 0) vec2 Scale;\n"
"uniform layout (location = 1) vec2 ViewportOrigin;\n"
"\n"
"in layout (origin_upper_left) vec2 gl_FragCoord;\n"
"\n"
"void main()\n"
"{\n"
"#ifdef IMAGE_U8\n"
"    vec2 coord = TexCoord0 * Scale;\n"
"    if (coord.x >= 1.0f || coord.y >= 1.0f)\n"
"        FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
"    else\n"
"        FragColor = vec4(texture(gSampler, TexCoord0 * Scale).rrr, 1.0f);\n"
"#elif defined IMAGE_RGB\n"
"    int x = int((gl_FragCoord.x - ViewportOrigin.x) * Scale.x);\n"
"    int y = int((gl_FragCoord.y - ViewportOrigin.y) * Scale.y);\n"
"\n"
"    FragColor.r = texelFetch(gSampler, ivec2(x * 3, y), 0).r;\n"
"    FragColor.g = texelFetch(gSampler, ivec2(x * 3 + 1, y), 0).r;\n"
"    FragColor.b = texelFetch(gSampler, ivec2(x * 3 + 2, y), 0).r;\n"
"    FragColor.a = 1.0f;\n"
"#elif defined IMAGE_RGBX\n"
"    vec2 coord = TexCoord0 * Scale;\n"
"    if (coord.x >= 1.0f || coord.y >= 1.0f)\n"
"        FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
"    else\n"
"        FragColor = texture(gSampler, coord);\n"
"#else\n"
"# error \"Image format is not specified\"\n"
"#endif\n"
"}\n"
"\n"
"";

const char * arrow_render_shader_fs_code = 
"uniform layout (location = 0) vec4 gColor;\n"
"out vec4 FragColor;\n"
"\n"
"void main()\n"
"{\n"
"    FragColor = gColor;\n"
"}\n"
"\n"
"";

const char * nv12image_render_shader_fs_code = 
"in vec2 TexCoord0;\n"
"out vec4 FragColor;\n"
"\n"
"uniform layout (binding = 0) sampler2D gSamplerY;\n"
"uniform layout (binding = 1) sampler2D gSamplerUV;\n"
"uniform layout (location = 0) vec2 Scale;\n"
"uniform layout (location = 1) vec2 ViewportOrigin;\n"
"\n"
"in layout (origin_upper_left) vec2 gl_FragCoord;\n"
"\n"
"void main()\n"
"{\n"
"    int x = int((gl_FragCoord.x - ViewportOrigin.x) * Scale.x);\n"
"    int y = int((gl_FragCoord.y - ViewportOrigin.y) * Scale.y);\n"
"\n"
"    vec2 UV = texelFetch(gSamplerUV, ivec2(x >> 1, y >> 1), 0).rg * vec2(255.0f, 255.0f);\n"
"    float Y = texelFetch(gSamplerY, ivec2(x, y), 0).r * 255.0f,\n"
"          Cb = UV.r, Cr = UV.g;\n"
"\n"
"    const bool FULL = true, BT709 = true;\n"
"    float Yf, Pb, Pr;\n"
"\n"
"    if (FULL)\n"
"    {\n"
"\n"
"        Yf = Y;\n"
"        Pb = Cb - 128.0f;\n"
"        Pr = Cr - 128.0f;\n"
"    }\n"
"    else\n"
"    {\n"
"        Yf = (Y - 16.0f) / 219.0f;\n"
"        Pb = (Cb - 128.0f) / 224.0f;\n"
"        Pr = (Cr - 128.0f) / 224.0f;\n"
"    }\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"    float Rf, Gf, Bf;\n"
"\n"
"    if (BT709)\n"
"    {\n"
"        Rf = Yf + 1.574800000f * Pr;\n"
"        Gf = Yf - 0.468124273f * Pr - 0.187324273f * Pb;\n"
"        Bf = Yf                     + 1.855600000f * Pb;\n"
"    }\n"
"    else\n"
"    {\n"
"        Rf = Yf + 1.402000000f * Pr;\n"
"        Gf = Yf - 0.714136286f * Pr - 0.344136286f * Pb;\n"
"        Bf = Yf                     + 1.772000000f * Pb;\n"
"    }\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"    float R, G, B;\n"
"\n"
"    if (FULL)\n"
"    {\n"
"\n"
"        R = Rf;\n"
"        G = Gf;\n"
"        B = Bf;\n"
"    }\n"
"    else\n"
"    {\n"
"        R = Rf * 219.0f + 16.5f;\n"
"        G = Gf * 219.0f + 16.5f;\n"
"        B = Bf * 219.0f + 16.5f;\n"
"    }\n"
"\n"
"    FragColor.r = R / 255.0f;\n"
"    FragColor.g = G / 255.0f;\n"
"    FragColor.b = B / 255.0f;\n"
"    FragColor.a = 1.0f;\n"
"}\n"
"\n"
"";

const char * feature_render_shader_fs_code = 
"#ifdef PER_FEATURE_STYLE\n"
"in vec4 Color;\n"
"#else\n"
"uniform layout (location = 0) vec4 Color;\n"
"#endif\n"
"\n"
"out vec4 FragColor;\n"
"\n"
"void main()\n"
"{\n"
"    vec2 temp = gl_PointCoord - vec2(0.5f);\n"
"    float f = dot(temp, temp);\n"
"    if (f > 0.25f)\n"
"        discard;\n"
"\n"
"    FragColor = Color;\n"
"}\n"
"\n"
"";

const char * rectangle_render_shader_fs_code = 
"out vec4 FragColor;\n"
"uniform layout (location = 0) vec4 gColor;\n"
"\n"
"void main()\n"
"{\n"
"    FragColor = gColor;\n"
"}\n"
"\n"
"";

const char * point_cloud_render_shader_fs_code = 
"in vec4 rast_color;\n"
"out vec4 out_Color;\n"
"\n"
"void main()\n"
"{\n"
"    vec2 temp = gl_PointCoord - vec2(0.5f);\n"
"    float f = dot(temp, temp);\n"
"    if (f > 0.25f) discard;\n"
"    out_Color = rast_color;\n"
"}\n"
"\n"
"";

const char * textbg_render_shader_fs_code = 
"out vec4 FragColor;\n"
"uniform layout (location = 0) vec4 color;\n"
"\n"
"void main(void)\n"
"{\n"
"    FragColor = color;\n"
"}\n"
"\n"
"";

const char * fence_plane_render_shader_fs_code = 
"in vec3 rast_color;\n"
"out vec4 color;\n"
"\n"
"void main()\n"
"{\n"
"    color = vec4(rast_color, 0.3f);\n"
"}\n"
"\n"
"";

const char * text_render_shader_fs_code = 
"in vec2 texcoord;\n"
"out vec4 FragColor;\n"
"\n"
"uniform layout (binding = 0) sampler2D tex;\n"
"uniform layout (location = 0) vec4 color;\n"
"\n"
"void main(void)\n"
"{\n"
"    float a = texture(tex, texcoord).x;\n"
"    FragColor = vec4(a * color.rgb, a * color.a);\n"
"}\n"
"\n"
"";

const char * textbg_render_shader_vs_code = 
"layout (location = 0) in vec2 coord;\n"
"\n"
"void main(void)\n"
"{\n"
"    gl_Position = vec4(coord.xy, 0, 1);\n"
"}\n"
"\n"
"";

const char * image_render_shader_vs_code = 
"out gl_PerVertex\n"
"{\n"
"    vec4 gl_Position;\n"
"};\n"
"\n"
"layout (location = 0) in vec2 Position;\n"
"layout (location = 1) in vec2 TexCoord;\n"
"\n"
"out vec2 TexCoord0;\n"
"\n"
"void main()\n"
"{\n"
"    gl_Position = vec4(Position, 0.0f, 1.0f);\n"
"    TexCoord0 = TexCoord;\n"
"}\n"
"\n"
"";

const char * feature_render_shader_vs_code = 
"out gl_PerVertex\n"
"{\n"
"    vec4 gl_Position;\n"
"    float gl_PointSize;\n"
"};\n"
"\n"
"layout (location = 0) in vec2 Position;\n"
"layout (location = 1) in int TrackingStatus;\n"
"\n"
"uniform layout (location = 0) vec2 Scale;\n"
"\n"
"#ifdef PER_FEATURE_STYLE\n"
"\n"
"struct FeatureStyle\n"
"{\n"
"    vec4 color[4];\n"
"    float radius;\n"
"};\n"
"\n"
"layout (location = 2) in vec4 StyleColor;\n"
"layout (location = 3) in float StyleRadius;\n"
"out vec4 Color;\n"
"\n"
"#else\n"
"\n"
"uniform layout (location = 1) float Radius;\n"
"\n"
"#endif\n"
"\n"
"#ifdef WITH_KEYPOINTS\n"
"\n"
"bool getTrackingStatus()\n"
"{\n"
"    return TrackingStatus != -1;\n"
"}\n"
"\n"
"#elif defined WITH_POINTS\n"
"\n"
"bool getTrackingStatus()\n"
"{\n"
"    return Position.x != -1.0f && Position.y != -1.0f;\n"
"}\n"
"\n"
"#else\n"
"# error \"Unspecified features type\"\n"
"#endif\n"
"\n"
"void main()\n"
"{\n"
"    vec2 position = vec2(-1.0f, -1.0f);\n"
"\n"
"    if (getTrackingStatus())\n"
"        position = Position;\n"
"\n"
"    position.x = position.x * Scale.x - 1.0f;\n"
"    position.y = 1.0f - position.y * Scale.y;\n"
"\n"
"    gl_Position = vec4(position, 0.0f, 1.0f);\n"
"\n"
"#ifdef PER_FEATURE_STYLE\n"
"    Color = StyleColor;\n"
"    gl_PointSize = StyleRadius;\n"
"#else\n"
"    gl_PointSize = Radius;\n"
"#endif\n"
"}\n"
"\n"
"";

const char * point_cloud_render_shader_vs_code = 
"layout (location = 0) in vec3 in_position;\n"
"out vec4 rast_color;\n"
"\n"
"uniform layout (location = 0) mat4 MVP;\n"
"\n"
"uniform layout (location = 1) float max_distance;\n"
"uniform layout (location = 2) float min_distance;\n"
"uniform layout (location = 3) float distance_norm_scale;\n"
"\n"
"void main()\n"
"{\n"
"    gl_Position = MVP * vec4(in_position, 1.0f);\n"
"\n"
"    float distance_from_camera = length(in_position);\n"
"    float depth_cue = (clamp(distance_from_camera, min_distance, max_distance) -\n"
"                       min_distance) * distance_norm_scale;\n"
"\n"
"    gl_PointSize = 1.0f + (1.0f - depth_cue) * 7.0f;\n"
"\n"
"    rast_color = vec4(1.0f - depth_cue, depth_cue, 0.0f, 0.0f);\n"
"}\n"
"\n"
"";

const char * arrow_render_shader_vs_code = 
"layout (location = 0) in vec2 Position;\n"
"\n"
"void main()\n"
"{\n"
"    gl_Position = vec4(Position, 0.0f, 1.0f);\n"
"}\n"
"\n"
"\n"
"";

const char * line_render_shader_vs_code = 
"layout (location = 0) in vec2 Position;\n"
"uniform layout (location = 0) vec2 ScaleRatio;\n"
"\n"
"vec2 normalizePoint(vec2 p)\n"
"{\n"
"    vec2 pn;\n"
"\n"
"    pn.x = p.x * ScaleRatio.x - 1.0f;\n"
"    pn.y = 1.0f - p.y * ScaleRatio.y;\n"
"\n"
"    return pn;\n"
"}\n"
"\n"
"void main()\n"
"{\n"
"    gl_Position = vec4(normalizePoint(Position), 0.0f, 1.0f);\n"
"}\n"
"\n"
"";

const char * rectangle_render_shader_vs_code = 
"layout (location = 0) in vec2 Position;\n"
"\n"
"void main()\n"
"{\n"
"    gl_Position = vec4(Position, 0.0f, 1.0f);\n"
"}\n"
"\n"
"";

const char * text_render_shader_vs_code = 
"layout (location = 0) in vec4 coord;\n"
"out vec2 texcoord;\n"
"\n"
"void main(void)\n"
"{\n"
"    gl_Position = vec4(coord.xy, 0, 1);\n"
"    texcoord = coord.zw;\n"
"}\n"
"\n"
"";

const char * fence_plane_render_shader_vs_code = 
"layout (location = 0) in vec3 vertexPosition_modelspace;\n"
"\n"
"out vec3 rast_color;\n"
"\n"
"uniform layout (location = 0) mat4 MVP;\n"
"\n"
"uniform layout (location = 1) float max_distance;\n"
"uniform layout (location = 2) float min_distance;\n"
"uniform layout (location = 3) float distance_norm_scale;\n"
"\n"
"void main()\n"
"{\n"
"    gl_Position = MVP * vec4(vertexPosition_modelspace, 1.0f);\n"
"    float distance_from_camera = length(vertexPosition_modelspace);\n"
"    float depth_cue = (clamp(distance_from_camera, min_distance, max_distance) -\n"
"                             min_distance) * distance_norm_scale;\n"
"    rast_color = vec3(1.0f - depth_cue, depth_cue, 0.0f);\n"
"}\n"
"\n"
"";

const char * motion_field_compute_shader_cs_code = 
"layout (local_size_x = 16, local_size_y = 16) in;\n"
"\n"
"shared vec2 sharedMem[128];\n"
"\n"
"uniform layout (location = 0) vec2 ScaleRatio;\n"
"uniform layout (location = 1) float Scale;\n"
"uniform layout (location = 2) uint mf_Scale;\n"
"\n"
"const float PI_F = 3.141592654f;\n"
"\n"
"layout (std140, binding = 0) buffer PositionsBuffer\n"
"{\n"
"    vec4 Positions[];\n"
"};\n"
"\n"
"uniform layout (r32f, binding = 0) mediump readonly image2D Field;\n"
"\n"
"vec2 normalizePoint(vec2 p)\n"
"{\n"
"    vec2 pn;\n"
"\n"
"    pn.x = p.x * ScaleRatio.x - 1.0f;\n"
"    pn.y = 1.0f - p.y * ScaleRatio.y;\n"
"\n"
"    return pn;\n"
"}\n"
"\n"
"void main()\n"
"{\n"
"\n"
"    ivec2 currentCoords = ivec2((uint(float(gl_GlobalInvocationID.x) / Scale) / mf_Scale) * 2u,\n"
"                                (uint(float(gl_GlobalInvocationID.y) / Scale) / mf_Scale));\n"
"    vec2 currentValue = vec2(imageLoad(Field, currentCoords).r,\n"
"                             imageLoad(Field, currentCoords + ivec2(1, 0)).r);\n"
"\n"
"\n"
"    if (gl_LocalInvocationIndex >= 128u)\n"
"        sharedMem[gl_LocalInvocationIndex - 128u] = currentValue;\n"
"    barrier();\n"
"\n"
"    if (gl_LocalInvocationIndex < 128u)\n"
"        sharedMem[gl_LocalInvocationIndex] += currentValue;\n"
"    barrier();\n"
"\n"
"    for (uint size = 64u; size > 0u; size >>= 1u)\n"
"    {\n"
"        if (gl_LocalInvocationIndex < size)\n"
"            sharedMem[gl_LocalInvocationIndex] += sharedMem[size + gl_LocalInvocationIndex];\n"
"        barrier();\n"
"    }\n"
"\n"
"\n"
"    if (all(equal(gl_LocalInvocationID.xy, uvec2(0u, 0u))))\n"
"    {\n"
"        vec2 mv = sharedMem[0] / 256.0f;\n"
"\n"
"        vec2 p = vec2(gl_GlobalInvocationID.xy + 8u);\n"
"        vec2 q = p + mv;\n"
"\n"
"        float angle = atan(-mv.y, -mv.x);\n"
"        float hypotenuse = length(mv);\n"
"\n"
"        uint groupID = (gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x) * 3u;\n"
"\n"
"        if (hypotenuse < 1.0f || hypotenuse > 50.0f)\n"
"        {\n"
"\n"
"            Positions[groupID + 0u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"            Positions[groupID + 1u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"            Positions[groupID + 2u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"        }\n"
"        else\n"
"        {\n"
"            hypotenuse *= Scale;\n"
"            q.x = p.x - hypotenuse * cos(angle);\n"
"            q.y = p.y - hypotenuse * sin(angle);\n"
"\n"
"            vec2 nq = normalizePoint(q);\n"
"\n"
"            Positions[groupID + 0u] = vec4(normalizePoint(p), nq);\n"
"\n"
"            float tips_length = 9.0f * hypotenuse / 50.0f + 5.0f;\n"
"\n"
"            p.x = q.x + tips_length * cos(angle + PI_F / 6.0f);\n"
"            p.y = q.y + tips_length * sin(angle + PI_F / 6.0f);\n"
"            Positions[groupID + 1u] = vec4(normalizePoint(p), nq);\n"
"\n"
"            p.x = q.x + tips_length * cos(angle - PI_F / 6.0f);\n"
"            p.y = q.y + tips_length * sin(angle - PI_F / 6.0f);\n"
"            Positions[groupID + 2u] = vec4(normalizePoint(p), nq);\n"
"        }\n"
"    }\n"
"}\n"
"\n"
"";

const char * arrow_compute_shader_cs_code = 
"layout (local_size_x = 256) in;\n"
"\n"
"uniform layout (location = 0) vec2 ScaleRatio;\n"
"uniform layout (location = 1) int NumItems;\n"
"\n"
"const float PI_F = 3.141592654f;\n"
"\n"
"#ifdef WITH_POINTS\n"
"\n"
"struct FeatureType\n"
"{\n"
"    float x;\n"
"    float y;\n"
"};\n"
"\n"
"#elif defined WITH_NVXKEYPOINTS\n"
"\n"
"struct FeatureType\n"
"{\n"
"    float x;\n"
"    float y;\n"
"    float strength;\n"
"    float scale;\n"
"    float orientation;\n"
"    int tracking_status;\n"
"    float error;\n"
"};\n"
"\n"
"#elif defined WITH_VXKEYPOINTS\n"
"\n"
"struct FeatureType\n"
"{\n"
"    int x;\n"
"    int y;\n"
"    float strength;\n"
"    float scale;\n"
"    float orientation;\n"
"    int tracking_status;\n"
"    float error;\n"
"};\n"
"\n"
"#else\n"
"# error \"Unspecified feature type\"\n"
"#endif\n"
"\n"
"layout (std430, binding = 0) buffer OldPositionsBuffer\n"
"{\n"
"    FeatureType OldPositions[];\n"
"};\n"
"\n"
"layout (std430, binding = 1) buffer NewPositionsBuffer\n"
"{\n"
"    FeatureType NewPositions[];\n"
"};\n"
"\n"
"layout (std140, binding = 2) buffer ResultPositionsBuffer\n"
"{\n"
"    vec4 ResultPositions[];\n"
"};\n"
"\n"
"vec2 normalizePoint(vec2 p)\n"
"{\n"
"    vec2 pn;\n"
"\n"
"    pn.x = p.x * ScaleRatio.x - 1.0f;\n"
"    pn.y = 1.0f - p.y * ScaleRatio.y;\n"
"\n"
"    return pn;\n"
"}\n"
"\n"
"#if defined WITH_NVXKEYPOINTS || defined WITH_VXKEYPOINTS\n"
"\n"
"bool getTrackingStatus()\n"
"{\n"
"    return NewPositions[gl_GlobalInvocationID.x].tracking_status != -1;\n"
"}\n"
"\n"
"#elif defined WITH_POINTS\n"
"\n"
"bool getTrackingStatus()\n"
"{\n"
"    return NewPositions[gl_GlobalInvocationID.x].x != -1.0f &&\n"
"           NewPositions[gl_GlobalInvocationID.x].y != -1.0f;\n"
"}\n"
"\n"
"#else\n"
"# error \"Unspecified features type\"\n"
"#endif\n"
"\n"
"void main()\n"
"{\n"
"    uint id = gl_GlobalInvocationID.x * 3u;\n"
"\n"
"    if (gl_GlobalInvocationID.x >= uint(NumItems))\n"
"        return;\n"
"\n"
"    if (!getTrackingStatus())\n"
"    {\n"
"        ResultPositions[id + 0u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"        ResultPositions[id + 1u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"        ResultPositions[id + 2u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"    }\n"
"    else\n"
"    {\n"
"        vec2 p = vec2(OldPositions[gl_GlobalInvocationID.x].x,\n"
"                      OldPositions[gl_GlobalInvocationID.x].y),\n"
"             q = vec2(NewPositions[gl_GlobalInvocationID.x].x,\n"
"                      NewPositions[gl_GlobalInvocationID.x].y);\n"
"        vec2 diff = p - q;\n"
"\n"
"        float angle = atan(diff.y, diff.x);\n"
"        float hypotenuse = length(diff);\n"
"\n"
"        if (hypotenuse < 1.0f || hypotenuse > 50.0f)\n"
"        {\n"
"            ResultPositions[id + 0u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"            ResultPositions[id + 1u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"            ResultPositions[id + 2u] = vec4(-2.0f, -2.0f, -2.0f, -2.0f);\n"
"        }\n"
"        else\n"
"        {\n"
"\n"
"            q.x = p.x - hypotenuse * cos(angle);\n"
"            q.y = p.y - hypotenuse * sin(angle);\n"
"\n"
"            vec2 qn = normalizePoint(q);\n"
"\n"
"            float tips_length = 9.0f * hypotenuse / 50.0f + 5.0f;\n"
"            ResultPositions[id + 0u] = vec4(qn, normalizePoint(p));\n"
"\n"
"            p.x = q.x + tips_length * cos(angle + PI_F / 6.0f);\n"
"            p.y = q.y + tips_length * sin(angle + PI_F / 6.0f);\n"
"            ResultPositions[id + 1u] = vec4(qn, normalizePoint(p));\n"
"\n"
"            p.x = q.x + tips_length * cos(angle - PI_F / 6.0f);\n"
"            p.y = q.y + tips_length * sin(angle - PI_F / 6.0f);\n"
"            ResultPositions[id + 2u] = vec4(qn, normalizePoint(p));\n"
"        }\n"
"    }\n"
"}\n"
"\n"
"";

#endif // OPENGL_GLSL_SHADERS
